package com.gking.processHarvest.realm;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gking.processHarvest.entity.Master;
import com.gking.processHarvest.service.Master.MasterService;
import com.gking.processHarvest.service.Role.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private MasterService masterService;

    @Autowired
    private RoleService roleService;


    //自定义授权方法：获取当前登录用户权限信息，返回给 Shiro 用来进行授权对比
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //1、获取用户身份信息
        String userId = principalCollection.getPrimaryPrincipal().toString();
        log.warn("自定义授权方法，查询到的用户 userId : {}", userId);

        //2、调用业务层获取用户信息(数据库)
        List<String> roleList = roleService.getUserRoleListByUserId(userId);
        log.warn("当前用户角色信息 = " + roleList);
        //2.1 调用业务层获取用户的权限信息（数据库）
        List<String> permissionsList = roleService.getUserPermissionsListByRoles(roleList);
        log.warn("当前用户权限信息 = " + permissionsList);

        //3、 创建对象，存储当前登录的用户的权限和角色
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roleList);
        info.addStringPermissions(permissionsList);

        //4、 返回信息
        return info;
    }


    //自定义登录认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1、获取用户身份信息
        String userId = authenticationToken.getPrincipal().toString();

        Master user = masterService.getById(userId);
        log.warn("shiro 获取用户身份信息 userId : " + userId);
        log.warn("shiro 用户信息 user : " + user);

        //3、非空判断，将数据封装返回
        if (user == null) return null;

        Md5Hash md5Hash = new Md5Hash(user.getPassword(), "salt", 3);
        AuthenticationInfo info = new SimpleAuthenticationInfo(
                authenticationToken.getPrincipal(),//用户标识
                md5Hash.toHex(),//密码
                ByteSource.Util.bytes("salt"),//加密时的盐
                authenticationToken.getPrincipal().toString()//realm name
        );

        return info;
    }


    //清除用户缓存
    public void clearCached() {
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        log.warn("清除缓存 principals： {}", principals);
        super.clearCache(principals);
    }

}
